#include "ds130x.h"

#ifdef __cplusplus
 extern "C" {
#endif

void Init_DS130X(void)
{
  /* init pin RES */
  GPIO_InitTypeDef  GPIO_InitStructure;
  RCC_AHB1PeriphClockCmd(RES_CLK, ENABLE);
  
  GPIO_InitStructure.GPIO_Pin = RES_DS1302;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
  GPIO_Init(RES_PORT, &GPIO_InitStructure);
  /* set pin RES */
  GPIO_ResetBits(RES_PORT,RES_DS1302);
  
  /* init module I2C */
  InitLowLevel_I2C(CHANNEL_I2Cx);
}

uint8_t BCDtoDec(uint8_t byte, uint8_t mask)
{
  uint8_t u8Low, u8Hight ;
  byte &= mask ;
  u8Low = byte & 0x0F ;
  u8Hight = ((byte >> 4) & 0x0F) * 10 ;
  return (u8Low + u8Hight);
}

uint8_t DectoBCD(uint8_t byte, uint8_t mask)
{
  uint8_t u8Low, u8Hight ;
  u8Hight = (byte / 10) << 4;
  u8Low = byte % 10;
  return ((u8Low | u8Hight) & mask);
}

void WriteTime_DS130X(typeTime *inputTime)
{
  ReqArrayData_I2C tempTime;
  uint8_t data[LENGTH_DATA];
  
  tempTime.DataLength_I2C = LENGTH_DATA;
  
#ifdef _DS1302_
  tempTime.DeviceAddress_I2C = ADDRESS_DEVICE_DS1302;
  tempTime.DataAddress_I2C = ADDRESS_SEC | MASK_WRITE_ADDRESS;
#endif /* _DS1302_ */
  
#ifdef _DS1307_
  tempTime.DeviceAddress_I2C = ADDRESS_DEVICE_DS1302 | MASK_READ_ADDRESS;
  tempTime.DataAddress_I2C = ADDRESS_SEC;
#endif /* _DS1307_ */
  
  data[0] = DectoBCD(inputTime->Sec, MASK_SEC);
  data[1] = DectoBCD(inputTime->Min, MASK_MIN);
  if (0 == inputTime->M12_24)
  {
    data[2] = DectoBCD(inputTime->Hour, MASK_HR_24);
  }
  else
  {
    data[2] = DectoBCD(inputTime->Hour, MASK_HR_12);
  }
  data[3] = DectoBCD(inputTime->Day, MASK_DAY);
  data[4] = DectoBCD(inputTime->Date, MASK_DATE);
  data[5] = DectoBCD(inputTime->Month, MASK_MONTH);
  data[6] = DectoBCD(inputTime->Year, MASK_YEAR);
  
  tempTime.Data_I2C = data;
  GPIO_SetBits(RES_PORT, RES_DS1302);
  WritePolling_I2C(CHANNEL_I2Cx, &tempTime);
  GPIO_ResetBits(RES_PORT, RES_DS1302);
}

void ReadTime_DS130X(typeTime *inputTime)
{
  ReqArrayData_I2C tempTime;
  uint8_t data[LENGTH_DATA];
  tempTime.Data_I2C = data;
  
  /* read second */
  tempTime.DataLength_I2C = LENGTH_DATA;
  
#ifdef _DS1302_
  tempTime.DeviceAddress_I2C = ADDRESS_DEVICE_DS1302;
  tempTime.DataAddress_I2C = ADDRESS_SEC | MASK_READ_ADDRESS;
#endif
  
#ifdef _DS1307_
  tempTime.DeviceAddress_I2C = ADDRESS_DEVICE_DS1302 | MASK_READ_ADDRESS;
  tempTime.DataAddress_I2C = ADDRESS_SEC;
#endif
  GPIO_SetBits(RES_PORT,RES_DS1302);
  ReadPolling_I2C(CHANNEL_I2Cx, &tempTime);
  GPIO_ResetBits(RES_PORT,RES_DS1302);
  
  /* process time */  
  inputTime->Sec = BCDtoDec(tempTime.Data_I2C[0], MASK_SEC);
  inputTime->Min = BCDtoDec(tempTime.Data_I2C[1], MASK_MIN);
  if (0 == inputTime->M12_24)
  {
    inputTime->Hour = BCDtoDec(tempTime.Data_I2C[2], MASK_HR_24);
  }
  else
  {
    inputTime->Hour = BCDtoDec(tempTime.Data_I2C[2], MASK_HR_12);
  }
  inputTime->Day = BCDtoDec(tempTime.Data_I2C[3], MASK_DAY);
  inputTime->Date = BCDtoDec(tempTime.Data_I2C[4], MASK_DATE);
  inputTime->Month = BCDtoDec(tempTime.Data_I2C[5], MASK_MONTH);
  inputTime->Year = BCDtoDec(tempTime.Data_I2C[6], MASK_YEAR);
}


#ifdef __cplusplus
}
#endif
